package com.scau402.system.controller;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.scau402.common.constant.InboundConstants;
import com.scau402.common.utils.SecurityUtils;
import com.scau402.system.domain.*;
import com.scau402.system.service.*;
import com.scau402.system1.domain.po.WmsWarehouseDO;
import com.scau402.system1.service.impl.WmsWarehouseService;
import com.scau402.system1.service.impl.WmsWarehouseStorageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.scau402.common.annotation.Log;
import com.scau402.common.core.controller.BaseController;
import com.scau402.common.core.domain.AjaxResult;
import com.scau402.common.enums.BusinessType;
import com.scau402.common.utils.poi.ExcelUtil;
import com.scau402.common.core.page.TableDataInfo;

import static com.scau402.system.constants.SystemConstants.*;

/**
 * 商品入库单Controller
 * 
 * @author ruoyi
 * @date 2023-06-26
 */
@RestController
@RequestMapping("/system/inboundOrder")
@Slf4j
public class WmsInboundOrderController extends BaseController
{
    @Autowired
    private IWmsInboundOrderService wmsInboundOrderService;

    @Autowired
    private ISysTenantService tenantService;

    @Autowired
    private IWmsInboundOrderMergeService inboundOrderMergeService;

    @Autowired
    private IWmsOutboundOrderService wmsOutboundOrderService;

    @Autowired
    private IWmsJadeService wmsJadeService;

    @Autowired
    private WmsWarehouseService wmsWarehouseService;

    @Autowired
    private WmsWarehouseStorageService wmsWarehouseStorageService;

    @Autowired
    private IWmsBasicSupplierService wmsBasicSupplierService;


    /**
     * 查询商品入库单列表
     */
    @PreAuthorize("@ss.hasPermi('system:inboundOrder:list')")
    @GetMapping("/list")
    public TableDataInfo list(WmsInboundOrder wmsInboundOrder)
    {
        startPage();
        List<WmsInboundOrder> list = wmsInboundOrderService.selectWmsInboundOrderList(wmsInboundOrder);
        list = wmsInboundOrderService.getDetails(list);
        return getDataTable(list);
    }

    /**
     * 导出商品入库单列表
     */
    @PreAuthorize("@ss.hasPermi('system:inboundOrder:export')")
    @Log(title = "商品入库单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, WmsInboundOrder wmsInboundOrder)
    {
        List<WmsInboundOrder> list = wmsInboundOrderService.selectWmsInboundOrderList(wmsInboundOrder);
        ExcelUtil<WmsInboundOrder> util = new ExcelUtil<WmsInboundOrder>(WmsInboundOrder.class);
        util.exportExcel(response, list, "商品入库单数据");
    }

    /**
     * 获取商品入库单详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:inboundOrder:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(wmsInboundOrderService.selectWmsInboundOrderById(id));
    }

    /**
     * 新增入库单（入库操作）
     * @param wmsInboundOrder 入库单信息
     * @return
     * @throws InterruptedException
     */
    @PreAuthorize("@ss.hasPermi('system:inboundOrder:add')")
    @Log(title = "商品入库单", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody WmsInboundOrder wmsInboundOrder) throws InterruptedException {

        // 设置入库单租户ID
        wmsInboundOrder.setTenantId(getLoginUser().getTenantId());

        // 判断入库数量是否为零
        if(wmsInboundOrder.getTotalQuantity().equals(InboundConstants.INBOUND_QUANTITY_ZERO)) {
            return error(QUANTITY_ZERO);
        }

        // 判断翡翠编码对应翡翠货品是否存在
        if(wmsJadeService.checkJadeExist(wmsInboundOrder.getJades())) {
            return error(JADE_EXIST);
        }

        // 检查是否允许入库
        if(!wmsWarehouseService.checkInOK(wmsInboundOrder.getDesWarehouseId())) {
            return error(INBOARD_REFUSED);
        }

        // 检查仓库容量
        // 入库单仓库 ID 非空
        if(wmsInboundOrder.getDesWarehouseId() != null) {
            //只获取一次数据库信息实体类，不为空直接判断，不进行二次获取
            WmsWarehouseDO wmsWarehouseDO = wmsWarehouseService.selectWmsWarehouseById(wmsInboundOrder.getDesWarehouseId());
            //不存在对应仓库
            if (wmsWarehouseDO == null) return error(WAREHOUSE_NOT_EXIST);
//            // 数据库存在仓库信息
//            if(wmsWarehouseService.selectWmsWarehouseById(wmsInboundOrder.getDesWarehouseId()) != null) {
                // 仓库是否已满
                if(wmsWarehouseService.checkFull(wmsInboundOrder.getDesWarehouseId())) {
                    return error(WAREHOUSE_NO_SPACE);
                }
//            } else {
//                return error(WAREHOUSE_NOT_EXIST);
//            }
        } else {
            return error(WAREHOUSE_ID_EMPTY);
        }

        // 检查仓位容量
        // 入库单仓位 ID 非空
        boolean toStorage = false; // 是否入库到仓位
        if(wmsInboundOrder.getDesStorageId() != null) {
            // 数据库存在仓位信息
            if(wmsWarehouseStorageService.selectWmsWarehouseStorageById(wmsInboundOrder.getDesStorageId()) != null) {
                // 仓位是否已满
                // TODO  2023/12/29 15:49: 跟下面的 checkFull 逻辑相反的，很奇怪
                if(wmsWarehouseStorageService.checkFull(wmsInboundOrder.getDesStorageId())) {
                    return error("仓位已满");
                }
                // 入库到仓位
                toStorage = true;
            }
        }

        // 检查入库单号是否存在
        if(wmsInboundOrderService.checkExists(wmsInboundOrder) == InboundConstants.INBOUND_ORDER_NOT_EXIST) {
            // 入库单不存在，创建入库单
            // 添加入库单
            // 设置翡翠货品数量
            wmsInboundOrder.setJadeQuantity(wmsInboundOrder.getTotalQuantity());
            // 设置翡翠还货数量
            wmsInboundOrder.setJades(wmsJadeService.setNewReturnQuantity(wmsInboundOrder));
            // 设置已还货数量，新建入库单该值初始为 0
            wmsInboundOrder.setReturnQuantity(InboundConstants.INBOUND_RETURN_QUANTITY_DEFAULT);
            // 设置未还货数量，为订单类型为借入（orderType=“1”）的翡翠货品数量
            wmsInboundOrder.setNotReturnQuantity(wmsInboundOrderService.getTotalBorrowQuantity(wmsInboundOrder));
            // 设置入库单翡翠标签价
            wmsInboundOrder.setJadeTagPrice(wmsInboundOrder.getTotalJadeTagPrice());
            // 设置入库单翡翠供货价
            wmsInboundOrder.setJadeSupplyPrice(wmsInboundOrder.getTotalJadeSupplyPrice());
            // 设置入库单翡翠成本价
            wmsInboundOrder.setJadeCost(wmsInboundOrder.getTotalJadeCost());
            // 设置入库单翡翠市场价
            wmsInboundOrder.setJadeMarketPrice(wmsInboundOrder.getTotalJadeMarketPrice());
            // 设置为未被合并
            wmsInboundOrder.setMerged(InboundConstants.INBOUND_MERGE_STATUS_UNMERGED);
            // 更新仓库库存数量
            // TODO  2023/12/23 15:23: 方法未完善
            wmsWarehouseService.updateQuantity(wmsInboundOrder);
            // 更新仓位库存数量
            if(toStorage) {
                wmsWarehouseStorageService.updateQuantity(wmsInboundOrder);
            }
            // 更新翡翠货品信息
            wmsJadeService.insertJades(wmsInboundOrder, wmsInboundOrder.getOrderCode());
            // 插入数据
            return toAjax(wmsInboundOrderService.insertWmsInboundOrder(wmsInboundOrder));
        } else {
            // 入库单已存在，更新入库单
            // 获取入库单
            WmsInboundOrder existInboundOrder = wmsInboundOrderService.selectWmsInboundOrderByOrderCode(wmsInboundOrder.getOrderCode());
            // 更新数据
            // 更新入库单翡翠数量
            existInboundOrder.setJadeQuantity(existInboundOrder.getJadeQuantity() + wmsInboundOrder.getTotalQuantity());
            // 设置翡翠还货数量
            wmsInboundOrder.setJades(wmsJadeService.setNewReturnQuantity(wmsInboundOrder));
            // 设置已还货数量
            // existInboundOrder.setReturnQuantity(existInboundOrder.getReturnQuantity() + wmsInboundOrderService.getTotalReturnQuantity(wmsInboundOrder));
            // 设置未还货数量
            existInboundOrder.setNotReturnQuantity(existInboundOrder.getNotReturnQuantity() + wmsInboundOrderService.getTotalBorrowQuantity(wmsInboundOrder));
            // 更新入库单翡翠标签价
            existInboundOrder.setJadeTagPrice(existInboundOrder.getJadeTagPrice().add(wmsInboundOrder.getTotalJadeTagPrice()));
            // 更新入库单翡翠供货价
            existInboundOrder.setJadeSupplyPrice(existInboundOrder.getJadeSupplyPrice().add(wmsInboundOrder.getTotalJadeSupplyPrice()));
            // 更新入库单翡翠成本价
            existInboundOrder.setJadeCost(existInboundOrder.getJadeCost().add(wmsInboundOrder.getTotalJadeCost()));
            // 更新入库单翡翠市场价
            existInboundOrder.setJadeMarketPrice(existInboundOrder.getJadeMarketPrice().add(wmsInboundOrder.getTotalJadeMarketPrice()));
            // 更新仓库库存数量
            wmsWarehouseService.updateQuantity(wmsInboundOrder);
            // 更新仓位库存数量
            if(toStorage) {
                wmsWarehouseStorageService.updateQuantity(wmsInboundOrder);
            }
            // 更新翡翠货品信息
            wmsJadeService.insertJades(wmsInboundOrder, wmsInboundOrder.getOrderCode());
            // 插入数据
            return toAjax(wmsInboundOrderService.updateWmsInboundOrder(existInboundOrder));
        }
    }

    /**
     * 修改商品入库单
     */
    @PreAuthorize("@ss.hasPermi('system:inboundOrder:edit')")
    @Log(title = "商品入库单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody WmsInboundOrder wmsInboundOrder)
    {
        return toAjax(wmsInboundOrderService.updateWmsInboundOrder(wmsInboundOrder));
    }

    /**
     * 删除商品入库单
     */
    @PreAuthorize("@ss.hasPermi('system:inboundOrder:remove')")
    @Log(title = "商品入库单", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(wmsInboundOrderService.deleteWmsInboundOrderByIds(ids));
    }

    @PreAuthorize("@ss.hasPermi('system:inboundOrder:add')")
    @GetMapping("/getInboundOrderCode")
    public String getInboundOrderCode() throws InterruptedException {
        // 返回租户编码
        return wmsInboundOrderService.getNewCode(SecurityUtils.getLoginUser().getUser());
    }

    /**
     * 入库单合并
     */
    @PreAuthorize("@ss.hasPermi('system:inboundOrder:add')")
    @Log(title = "入库单合并", businessType = BusinessType.INSERT)
    @PostMapping("/merge")
    public AjaxResult merge(@RequestBody String params) throws InterruptedException {
        // 转换 source_ids 为 list 格式
        JSONObject paramsJson =  JSON.parseObject(params);
        JSONArray jsonArray = paramsJson.getJSONArray("mergeOrderIds");
        List<Long> ids = JSONArray.parseArray(jsonArray.toJSONString(), Long.class);

        // 获取新入库单编码并写入数据库
        String newOrderCode = getInboundOrderCode();
        WmsInboundOrder newInboundOrder = new WmsInboundOrder();
        //初始化数据
        newInboundOrder.setJadeCost(new BigDecimal(0));
        newInboundOrder.setJadeWeight(new BigDecimal(0));
        newInboundOrder.setJadeQuantity(0l);
        newInboundOrder.setJadeTagPrice(new BigDecimal(0));
        newInboundOrder.setJadeMarketPrice(new BigDecimal(0));
        newInboundOrder.setJadeSupplyPrice(new BigDecimal(0));
        newInboundOrder.setOrderCode(newOrderCode);
        newInboundOrder.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());

        List<Long> mergeIds = new ArrayList<Long>(ids.size());

        for(int i=0; i<ids.size(); i++) {
            WmsInboundOrder inboundOrder = wmsInboundOrderService.selectWmsInboundOrderById(ids.get(i));
            if(!(inboundOrder.getOrderType().equals(InboundConstants.INBOUND_ORDER_TYPE_BUY) || inboundOrder.getOrderType().equals(InboundConstants.INBOUND_ORDER_TYPE_BORROW))) {
                return error("只能合并采购入库单");
            }
        }

        for(int i=0; i<ids.size(); i++) {
            // 更新被合并入库单的状态
            WmsInboundOrder inboundOrder = wmsInboundOrderService.selectWmsInboundOrderById(ids.get(i));

            inboundOrder.setStatus(InboundConstants.INBOUND_STATUS_ENABLE);
            inboundOrder.setMerged(InboundConstants.INBOUND_MERGE_STATUS_MERGED);
            wmsInboundOrderService.updateWmsInboundOrder(inboundOrder);

            // 计算合并数据
            // 成本
            newInboundOrder.setJadeCost(inboundOrder.getJadeCost().add(newInboundOrder.getJadeCost()));
            // 重量
            newInboundOrder.setJadeWeight(inboundOrder.getJadeWeight().add(newInboundOrder.getJadeWeight()));
            // 数量
            newInboundOrder.setJadeQuantity(inboundOrder.getJadeQuantity() + newInboundOrder.getJadeQuantity());
            // 标签价格
            newInboundOrder.setJadeTagPrice(inboundOrder.getJadeTagPrice().add(newInboundOrder.getJadeTagPrice()));
            // 市场价格
            newInboundOrder.setJadeMarketPrice(inboundOrder.getJadeMarketPrice().add(newInboundOrder.getJadeMarketPrice()));
            // 供货价格
            newInboundOrder.setJadeSupplyPrice(inboundOrder.getJadeSupplyPrice().add(newInboundOrder.getJadeSupplyPrice()));
            // 
            mergeIds.add(ids.get(i));
        }

        // 设置新入库单为合并后
        newInboundOrder.setMerged(InboundConstants.INBOUND_MERGE_STATUS_MERGED_RESULT);
        // 合并后订单类型设为采购
        newInboundOrder.setOrderType(InboundConstants.INBOUND_ORDER_TYPE_BUY);
        // 写入新合并单
        wmsInboundOrderService.insertWmsInboundOrder(newInboundOrder);

        // 获取新写入的入库单主键 ID
        Long newOrderId = wmsInboundOrderService.selectWmsInboundOrderIdByOrderCode(newOrderCode);

        // 写入合并入库单信息到数据库
        for(int i=0; i<mergeIds.size(); i++) {
            WmsInboundOrderMerge mergeData = new WmsInboundOrderMerge();
            mergeData.setNewOrderId(newOrderId);
            mergeData.setMergeOrderId(mergeIds.get(i));
            inboundOrderMergeService.insertWmsInboundOrderMerge(mergeData);
        }

        AjaxResult ajax = AjaxResult.success();
        ajax.put("newOrderId", newOrderId);
        return ajax;
    }

    /**
     * 获取入库单详细信息（合并后）
     *
     * @param params
     * @return
     * @throws InterruptedException
     */
    @PreAuthorize("@ss.hasPermi('system:inboundOrder:add')")
    @PostMapping("/getOrderDetail")
    public AjaxResult getOrderDetail(@RequestBody String params) throws InterruptedException {

        return toAjax(1);
    }


    /**
     * 获取入库货品列表
     *
     * @return
     */
    @PreAuthorize("@ss.hasPermi('system:inboundOrder:list')")
    @GetMapping("/inList")
    public TableDataInfo inList() {
        startPage();
        List<WmsJade> list = wmsJadeService.selectInboundJadeList(getLoginUser().getTenantId());
        return getDataTable(list);
    }

    /**
     * 翡翠图像ID找到对应翡翠货品
     *
     * @return
     */
    @PreAuthorize("@ss.hasPermi('system:inboundOrder:add')")
    @PostMapping("/getJadesByImageIds")
    public AjaxResult getJadesByImageIds(@RequestBody String params) {
        // 转换 sour - ce_ids 为 list 格式
        JSONObject paramsJson =  JSON.parseObject(params);
        JSONArray jsonArray = paramsJson.getJSONArray("imageIds");
        List<Long> imageIds = JSONArray.parseArray(jsonArray.toJSONString(), Long.class);

        // 获取对应翡翠货品
        List<WmsJade> jades = wmsJadeService.selectJadesByImageIds(imageIds);

        List<WmsJade> result = new ArrayList<WmsJade>();

        // 获取有对应借货出库记录的翡翠
        for(int i=0; i<jades.size(); i++) {
            String orderCode = jades.get(i).getOrderCode();
            WmsOutboundOrder outboundOrder = wmsOutboundOrderService.selectWmsInboundOrderByOrderCode(orderCode);

            // 数据库没有对应出库单记录
            if(outboundOrder == null) {
                continue;
            }

            // 是否为借货出库
            if(outboundOrder.getOrderType().equals(InboundConstants.INBOUND_ORDER_TYPE_BORROW)) {
                result.add(jades.get(i));
            }
        }

        if(result.size() == 0) {
            return success("翡翠没有对应借货出库记录");
        }
        return success(result);
    }



}
